package gentle.support.duplicateSubmission;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;

/**
 * @author:wwz
 */
@Aspect
@Component
public class RepeatSubmitAspect {
    @Autowired
    private RedisUtils redisUtils;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final static Object PRESENT = new Object();

    @Pointcut("@annotation(gentle.support.duplicateSubmission.RejectMultiPost)")
    public void pointcut() {
    }

    private final static class Holder {
        private static HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    @Around("pointcut()&& @annotation(rejectMultiPost)")
    public Object around(ProceedingJoinPoint joinPoint, RejectMultiPost rejectMultiPost) throws Throwable {
        Jedis jedis = null;
        //连接redis服务器，192.168.0.100:6379
        jedis = new Jedis("localhost", 6379);
        String key = Holder.request.getRequestURI()+jedis.get("userId");
        boolean lock = true;
        try {
            //设置解锁key
            lock = ResubmitLock.getInstance().lock(key, PRESENT);
            if (lock) {
                //放行
                return joinPoint.proceed(joinPoint.getArgs());
            } else {
                //响应重复提交异常
                logger.error("重复提交【代码未执行】");
                System.out.println("重复提交【代码未执行】");
                return "响应重复提交异常";
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "响应重复提交异常";
        } finally {
            //设置解锁key和解锁时间
            ResubmitLock.getInstance().unLock(lock, key, 5);
        }
    }
}